From 056cc862095ed2688c5b1d8d0d38ed4f904032aa Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Fri, 22 Sep 2017 14:50:48 +0200 Subject: [PATCH] babl: make babl_space_to_icc internal, for now Also adds an optimized 26 entry LUT, as used in the creation of http://pippin.gimp.org/sRGBz/ Please enter the commit message for your changes. Lines starting --- babl/babl-icc.c | 73 ++++++++++++++++++++++++++++------------ babl/babl-internal.h | 22 +++++++++++- babl/babl-space.c | 2 +- babl/babl.h | 11 ------ tools/babl-icc-rewrite.c | 66 ++++++++++++++++++++++++++++++------ 5 files changed, 129 insertions(+), 45 deletions(-) diff --git a/babl/babl-icc.c b/babl/babl-icc.c index b5e85fc..fe146f6 100644 --- a/babl/babl-icc.c +++ b/babl/babl-icc.c @@ -405,8 +405,18 @@ static void icc_duplicate_tag(ICC *state, const char *tag) icc_write (u32, 128 + 4 + 4 * state->headpos++, state->psize); } -void write_trc (ICC *state, const char *name, const BablTRC *trc); -void write_trc (ICC *state, const char *name, const BablTRC *trc) +/* brute force optimized 26 entry sRGB LUT */ +static const uint16_t lut_srgb_26[]={0,202,455,864,1423,2154,3060,4156,5454,6960,8689,10637,12821,15247,17920,20855,24042,27501,31233,35247,39549,44132,49018,54208,59695,65535}; + + +void write_trc (ICC *state, + const char *name, + const BablTRC *trc, + BablICCFlags flags); +void write_trc (ICC *state, + const char *name, + const BablTRC *trc, + BablICCFlags flags) { switch (trc->type) { @@ -436,10 +446,26 @@ switch (trc->type) break; // this is the case catching things not directly representable in v2 case BABL_TRC_SRGB: + if (flags == BABL_ICC_COMPACT_TRC_LUT) + { + int lut_size = 26; + icc_allocate_tag (state, name, 12 + lut_size * 2); + icc_write (sign, state->o, "curv"); + icc_write (u32, state->o + 4, 0); + icc_write (u32, state->o + 8, lut_size); + { + int j; + for (j = 0; j < lut_size; j ++) + icc_write (u16, state->o + 12 + j * 2, lut_srgb_26[j]); + } + break; + } case BABL_TRC_FORMULA_SRGB: -// default: { int lut_size = 512; + if (flags == BABL_ICC_COMPACT_TRC_LUT) + lut_size = 128; + icc_allocate_tag (state, name, 12 + lut_size * 2); icc_write (sign, state->o, "curv"); icc_write (u32, state->o + 4, 0); @@ -456,7 +482,11 @@ switch (trc->type) static void symmetry_test (ICC *state); -const char *babl_space_to_icc (const Babl *babl, int *ret_length) +const char *babl_space_to_icc (const Babl *babl, + const char *description, + const char *copyright, + BablICCFlags flags, + int *ret_length) { const BablSpace *space = &babl->space; static char icc[65536]; @@ -529,8 +559,7 @@ const char *babl_space_to_icc (const Babl *babl, int *ret_length) icc_write (s15f16, state->o + 12, space->RGBtoXYZ[5]); icc_write (s15f16, state->o + 16, space->RGBtoXYZ[8]); - - write_trc (state, "rTRC", &space->trc[0]->trc); + write_trc (state, "rTRC", &space->trc[0]->trc, flags); if (space->trc[0] == space->trc[1] && space->trc[0] == space->trc[2]) @@ -540,33 +569,33 @@ const char *babl_space_to_icc (const Babl *babl, int *ret_length) } else { - write_trc (state, "gTRC", &space->trc[1]->trc); - write_trc (state, "bTRC", &space->trc[2]->trc); + write_trc (state, "gTRC", &space->trc[1]->trc, flags); + write_trc (state, "bTRC", &space->trc[2]->trc, flags); } { - char str[128]; + char str[128]="CC0/public domain"; int i; - sprintf (str, "babl"); - icc_allocate_tag(state, "desc", 90 + strlen (str) + 0); - icc_write (sign, state->o,"desc"); + if (!copyright) copyright = str; + icc_allocate_tag(state, "cprt", 8 + strlen (copyright) + 1); + icc_write (sign, state->o, "text"); icc_write (u32, state->o + 4, 0); - icc_write (u32, state->o + 8, strlen(str) + 1); - for (i = 0; str[i]; i++) - icc_write (u8, state->o + 12 + i, str[i]); + for (i = 0; copyright[i]; i++) + icc_write (u8, state->o + 8 + i, copyright[i]); } - { - char str[128]; + char str[128]="babl"; int i; - sprintf (str, "CC0/public domain"); - icc_allocate_tag(state, "cprt", 8 + strlen (str) + 1); - icc_write (sign, state->o, "text"); + if (!description) description = str; + icc_allocate_tag(state, "desc", 90 + strlen (description) + 0); + icc_write (sign, state->o,"desc"); icc_write (u32, state->o + 4, 0); - for (i = 0; str[i]; i++) - icc_write (u8, state->o + 8 + i, str[i]); + icc_write (u32, state->o + 8, strlen(description) + 1); + for (i = 0; description[i]; i++) + icc_write (u8, state->o + 12 + i, description[i]); } + icc_write (u32, 0, state->no + 0); length = state->no + 0; } diff --git a/babl/babl-internal.h b/babl/babl-internal.h index efa593c..3a7676e 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -445,6 +445,26 @@ const Babl * babl_trc (const char *name); int _babl_file_get_contents (const char *path, char **contents, long *length, - void *error); + void *error); + +typedef enum { + BABL_ICC_DEFAULTS = 0, + BABL_ICC_COMPACT_TRC_LUT = 1, +} BablICCFlags; + +/* babl_space_to_icc: + * + * Creates an ICCv2 RGB matrix profile for a babl space. The profiles strive to + * be as small and compact as possible, TRCs are stored as 1024 entry LUT(s). + * + * you should make a copy of the profile before making another call to this + * function. + */ + +const char *babl_space_to_icc (const Babl *space, + const char *description, + const char *copyright, + BablICCFlags flags, + int *icc_length); #endif diff --git a/babl/babl-space.c b/babl/babl-space.c index 2ffd1de..a362521 100644 --- a/babl/babl-space.c +++ b/babl/babl-space.c @@ -175,7 +175,7 @@ static void babl_space_compute_matrices (BablSpace *space) double green_XYZ[3] = { _ xg / _ yg, 1.0, ( 1.0 - _ xg - _ yg) / _ yg}; double blue_XYZ[3] = { _ xb / _ yb, 1.0, ( 1.0 - _ xb - _ yb) / _ yb}; double whitepoint_XYZ[3] = { _ xw / _ yw, 1.0, ( 1.0 - _ xw - _ yw) / _ yw}; - double D50_XYZ[3] = {0.9642, 1.0, 0.8249}; + double D50_XYZ[3] = {0.96420288, 1.0, 0.82490540}; #undef _ double mat[9] = {red_XYZ[0], green_XYZ[0], blue_XYZ[0], diff --git a/babl/babl.h b/babl/babl.h index a7d75b5..9ab3881 100644 --- a/babl/babl.h +++ b/babl/babl.h @@ -145,17 +145,6 @@ char *babl_icc_get_key (const char *icc_data, const char *language, const char *counter); - -/* babl_space_to_icc: - * - * Creates an ICCv2 RGB matrix profile for a babl space. The profiles strive to - * be as small and compact as possible, TRCs are stored as 1024 entry LUT(s). - * - * you should make a copy of the profile before making another call to this - * function. - */ -const char *babl_space_to_icc (const Babl *space, int *icc_length); - /* babl_space_get_rgbtoxyz: Returns the internal, double-precision 3x3 matrix used to convert linear diff --git a/tools/babl-icc-rewrite.c b/tools/babl-icc-rewrite.c index f30b20e..e01994e 100644 --- a/tools/babl-icc-rewrite.c +++ b/tools/babl-icc-rewrite.c @@ -25,42 +25,85 @@ file_get_contents (const char *path, char **contents, long *length, void *error); + void file_set_contents (const char *path, const char *data, long length); int main (int argc, char **argv) { + BablICCFlags flags = 0; const Babl *babl; char *icc_data = NULL; long icc_len; int genlen; + char *description = NULL; + char *copyright = NULL; const char *error; const char *la = NULL; const char *co = NULL; + + const char *input = NULL; + const char *output = NULL; + int i; + babl_init (); - if (!argv[1] || !argv[2]) + + for (i = 1; argv[i]; i++) + { + if (!strcmp (argv[i], "-d") || + !strcmp (argv[i], "--description")) + { + description = argv[++i]; + } + else if (!strcmp (argv[i], "-c") || + !strcmp (argv[i], "--copyright")) + { + copyright = argv[++i]; + } + else if (!strcmp (argv[i], "--compact-trc")) + { + flags |= BABL_ICC_COMPACT_TRC_LUT; + } + else if (argv[i][0] == '-') + { + fprintf (stderr, "unknown option %s\n", argv[i]); + return -1; + } + else + { + if (!input) input = argv[i]; + else if (!output) output = argv[i]; + } + } + + if (!input || !output) { - fprintf (stderr, "usage: %s \n", argv[0]); + fprintf (stderr, "usage: %s [options] \n", argv[0]); + fprintf (stderr, " where recognized options are: \n"); + fprintf (stderr, " -d \n"); + fprintf (stderr, " -c \n"); + fprintf (stderr, " --compact-trc\n"); return -1; } - if (file_get_contents (argv[1], &icc_data, &icc_len, NULL)) + if (file_get_contents (input, &icc_data, &icc_len, NULL)) return -1; + if (!description) { - char *description = babl_icc_get_key (icc_data, icc_len, "description", la, co); + description = babl_icc_get_key (icc_data, icc_len, "description", la, co); if (description) fprintf (stderr, "description: %s\n", description); } + if (!copyright) { - char *str = babl_icc_get_key (icc_data, icc_len, "copyright", la, co); - if (str) + copyright = babl_icc_get_key (icc_data, icc_len, "copyright", la, co); + if (copyright) { - fprintf (stderr, "copyright: %s\n", str); - free (str); + fprintf (stderr, "copyright: %s\n", copyright); } } { @@ -87,11 +130,14 @@ main (int argc, return -1; } - icc_data = (char *)babl_space_to_icc (babl, &genlen); + icc_data = (char *)babl_space_to_icc (babl, description, + copyright, flags, + &genlen); if (icc_data) { - file_set_contents (argv[2], icc_data, genlen); + file_set_contents (output, icc_data, genlen); } + fprintf (stderr, "[%s]\n", output); babl_exit (); return 0; -- 2.30.2